home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / draw.cpp < prev    next >
C/C++ Source or Header  |  1994-11-10  |  22KB  |  789 lines

  1. #include <stdlib.h>
  2. #include "draw.h"
  3.  
  4. #include "dim.h"         // "Ruber" figures
  5. #include "icon.h"        // Used with microscope
  6. #include "edit.h"        // text output with LJ fonts, in Horiz and Vert directions
  7. #include "drawappl.h"
  8. #include "filter.h"
  9. #include "simple.h"
  10. #include <string.h>
  11. #include "imagebuf.h"
  12. #include "effects.h"
  13. #include "tools.h"
  14. #include "gbuf.h"
  15.  
  16. extern void fill_area(loc from, int a, int b, char* f, rect r); // FILL.CPP
  17.  
  18.  
  19. int* read_line_N(int num, char* fileName)        // Filter matrix
  20.     {                                            // reading from disk
  21.     FILE* filt = fopen(fileName, "r");
  22.     char* pat = new char[100];
  23.     for(int i = 0; i < num; i++)
  24.     {
  25.     pat = fgets(pat, 99, filt);
  26.     }
  27.     fclose(filt);
  28.     int* kernel = new int[9];
  29.     kernel[0] = atoi(strtok(pat, " ,;"));
  30.     for(int k = 1; k < 9; k++)
  31.     {
  32.     kernel[k] = atoi(strtok(NULL, " ,;"));
  33.     }
  34.     delete pat;
  35.     return kernel;
  36.     }
  37. ///////////////////////
  38. loc get_dither(int num, int* dither)
  39.     {                                               // x
  40.     FILE* dit;                            // y
  41.     if((dit = fopen("dither.src", "r")) == NULL)    // a1 b1 c1...
  42.     return loc(0, 0);
  43.     char* pat = new char[100];                      // ...
  44.                             // @
  45.     int i = 0;
  46.     while(i < num)                   // move to the given matrice
  47.     {
  48. //    fgets(pat, 99, dit);
  49.     if(fgets(pat, 99, dit) == NULL)
  50.         {
  51.         delete pat;
  52.             fclose(dit);
  53.         return loc(0, 0);
  54.         }
  55.     if(pat[0] == '@')
  56.         i++;
  57.     }
  58.  
  59.     pat = fgets(pat, 10, dit);    // read the matrice dimentions
  60.     int x = atoi(pat);
  61.     pat = fgets(pat, 10, dit);
  62.     int y = atoi(pat);
  63.     for(int j = 0; j < y; j++)
  64.     {
  65.     pat = fgets(pat, 99, dit);
  66.     dither[j * x] = (atoi(strtok(pat, " ,;")));
  67.     for(int k = 1; k < x; k++)
  68.         {
  69.         dither[j * x + k] = (atoi(strtok(NULL, " ,;")));
  70.         }
  71.     }
  72.     fclose(dit);
  73.     delete pat;
  74.     return loc(x, y);
  75.     }
  76. ///////////////////////
  77. Draw::Draw(rect coordinates)
  78.     : Window(coordinates, "", "", 0, NO_BORDER, NO_BORDER, FIXED, 0)
  79.     {
  80.     saved = 1;
  81.     }
  82. /////////////////////////
  83. Draw::~Draw()
  84.     {
  85.     kh_draw->askSave();
  86.     unlink("copy.pcy");
  87.     }
  88. ///////////////////////////
  89. loc Draw::verify_rect(rect r)
  90.     {
  91.     loc mspos = e.where();
  92.     if(mspos.X < r.origin.X)
  93.         mspos.X = r.origin.X;
  94.     if(mspos.X > r.corner.X)
  95.         mspos.X = r.corner.X;
  96.     if(mspos.Y < r.origin.Y)
  97.         mspos.Y = r.origin.Y;
  98.     if(mspos.Y > r.corner.Y)
  99.         mspos.Y = r.corner.Y;
  100.     return mspos;
  101.     }
  102. ////////////////////////
  103.  
  104. void mouse_move(loc ms)
  105.     {
  106.     mouseHideCursor();
  107.     mouseSetPosition(ms);
  108.     mouseShowCursor();
  109.     }
  110. //////////////////////////
  111. int Draw::do_scroll(int key, GrafBuffer* buf)
  112.     {
  113.     if(kh_draw->DATA_ZOOM)
  114.     return 1;
  115.     mouseHideCursor();
  116.     rect r = user_screen();
  117.  
  118.     switch(key)
  119.     {
  120.     case EVENT_LEFT:
  121.         buf->scroll(pScreenSet->cell_width * 2, RIGHT); break;
  122.     case EVENT_RIGHT:
  123.         buf->scroll(pScreenSet->cell_width * 2, LEFT); break;
  124.     case EVENT_UP:
  125.         buf->scroll(pScreenSet->cell_height * 2, DN); break;
  126.     case EVENT_DN:
  127.         buf->scroll(pScreenSet->cell_height * 2, UP); break;
  128.     case EVENT_HOME:
  129.         buf->scroll((r.width() / 4) / 8 * 8, RIGHT); break;
  130.     case EVENT_END:
  131.         buf->scroll((r.width() / 4 ) / 8 * 8, LEFT); break;
  132.     case EVENT_PG_UP:
  133.         buf->scroll((r.height() / 4), DN);
  134.         break;
  135.     case EVENT_PG_DN:
  136.         buf->scroll((r.height() / 4), UP);
  137.         break;
  138.     case EVENT_F1:
  139.         global_i[0] = action_type; return 1;
  140.     case EVENT_F6:
  141.     case EVENT_ESC:
  142.     case EVENT_F2:
  143.     case EVENT_F10:
  144.     case EVENT_TAB:
  145.         global_num = global_i[0] = 0; //unhilite();
  146.         mouseShowCursor(); return 1;
  147.     }
  148.     return 0;
  149.     }
  150. ////////////////////////
  151. void Draw::exe(int act)
  152.     {
  153.     if(!kh_draw->buffer->loaded)
  154.     {
  155.     e.what = KEYEVENT;
  156.     e.key = EVENT_F10;
  157.     global_num = global_i[0] = 0;
  158.     return;
  159.     }
  160.  
  161.     rect r = user_screen();
  162.     kh_draw->DATA_X = global_i[10];      // Message exchange between
  163.     kh_draw->DATA_Y = global_i[11];      // Microscope and Draw
  164.  
  165.     if(global_i[0] == AC_MICROSCOPE_2    // We exits MICROSCOPE with OK command
  166.     && !kh_draw->DATA_ZOOM)
  167.     {
  168.     void* image = get_image("copy.res", 1);
  169.     putimage(kh_draw->DATA_X, kh_draw->DATA_Y, image, COPY_PUT);
  170.     delete image;
  171.     kh_draw->DATA_X = kh_draw->DATA_Y = 0;
  172.     }
  173.     global_i[0] = action_type;
  174.  
  175.     if(kh_draw->DATA_TOOLS == TOOL_UNDO && !kh_draw->DATA_ZOOM)        // UNDO
  176.     {
  177.     mouseHideCursor();
  178.     if(pcx_file_scr("undo.pcy", r.origin))
  179.         unlink("undo.pcy");
  180.     else
  181.         {
  182.         kh_draw->buffer->b_open();
  183.         kh_draw->buffer->buffer_screen();
  184.         kh_draw->buffer->b_close();
  185.         }
  186.     mouseShowCursor();
  187.     }
  188.     else if(kh_draw->DATA_TOOLS != TOOL_LOCAL_UNDO && !kh_draw->DATA_ZOOM)
  189.     {
  190.     mouseHideCursor();
  191.     if(kh_draw->DATA_TRANS)
  192.         pcx_scr_file(r, "undo.pcy");
  193.     else
  194.         {
  195.         kh_draw->buffer->b_open();
  196.         kh_draw->buffer->screen_buffer();
  197.         kh_draw->buffer->b_close();
  198.         }
  199.     mouseShowCursor();
  200.     }
  201.  
  202.     int on = 0;
  203.     if(kh_draw->DATA_TOOLS == TOOL_SCROLL && !kh_draw->DATA_ZOOM)   // SCROLL
  204.     kh_draw->buffer->b_open();
  205.     loc ms = e.where();
  206.     while(1)
  207.     {
  208.     if((!act && !(e.what == MOUSEEVENT && !on))
  209.         || (kh_draw->DATA_TOOLS == TOOL_FILL))
  210.         get_event(1);            // We do not begin FILL it immediately
  211.     else
  212.         on = 1;
  213.     if(e.what == KEYEVENT && kh_draw->DATA_TOOLS != TOOL_SCROLL)
  214.         {
  215.         int z = (kh_draw->DATA_ZOOM > 0) ? kh_draw->DATA_ZOOM : 100;
  216.         rect reserv = r;
  217.         if(kh_draw->DATA_ZOOM)
  218.         r = rect(r.origin,
  219.             loc(r.origin.X + (long)kh_draw->buffer->buf_dim.X * 100 / z,
  220.             r.origin.Y + (long)kh_draw->buffer->buf_dim.Y * 100 / z));
  221.  
  222.         if(!(r.contains(e.where())))      // if mouse is outside the DRAW
  223.         {
  224.         mouseSetPosition(r.origin);   // set mouse inside DRAW
  225.             ms = r.origin;
  226.                 }
  227.         mouseSetRange(r);                 // block leaving DRAW using kbd
  228.         switch(e.key)
  229.         {
  230.         case EVENT_LEFT:
  231.             mouse_move(ms = loc(ms.X - pScreenSet->cell_width, ms.Y));
  232.                     readevent();
  233.             break;
  234.         case EVENT_RIGHT:
  235.             mouse_move(ms = loc(ms.X + pScreenSet->cell_width, ms.Y));
  236.             readevent();
  237.             break;
  238.         case EVENT_UP:
  239.             mouse_move(ms = loc(ms.X, ms.Y - pScreenSet->cell_height));
  240.                     readevent();
  241.             break;
  242.         case EVENT_DN:
  243.             mouse_move(ms = loc(ms.X, ms.Y + pScreenSet->cell_height));
  244.             readevent();
  245.             break;
  246.         case EVENT_HOME:
  247.             mouse_move(ms = r.origin);
  248.             readevent();
  249.             break;
  250.  
  251.         case EVENT_F1:
  252.             global_i[0] = action_type; mouseDefaultRange(); return;
  253.         case EVENT_F6:
  254.         case EVENT_F10:
  255.         case EVENT_TAB:
  256.         case EVENT_ALT_F3:
  257.         case EVENT_ALT_F4:
  258.         case EVENT_ALT_TAB:
  259.             if(!kh_draw->DATA_ZOOM)
  260.             {
  261.             kh_draw->buffer->b_open();
  262.             kh_draw->buffer->screen_buffer();
  263.             kh_draw->buffer->b_close();
  264.             }
  265.             global_num = global_i[0] = 0;
  266.             mouseDefaultRange(); r = reserv;
  267.             return;
  268.         case EVENT_F2:
  269.         case EVENT_RETURN:
  270.             mouseDefaultRange(); r = reserv;
  271.             draw();
  272.             break;
  273.         }
  274.         r = reserv;
  275.         mouseDefaultRange();
  276.         }
  277.     else if(e.what == KEYEVENT && !kh_draw->DATA_ZOOM)    // SCROLL
  278.         {
  279.         if(do_scroll(e.key, kh_draw->buffer))
  280.         return;
  281.         }
  282.     else
  283.         {
  284.         if(!mouse_in(e.where()))    // outside of draw box
  285.         {
  286.         global_num = global_i[0] = 0;
  287.                 if(!kh_draw->DATA_ZOOM && !kh_draw->w1->mouse_in(e.where()))
  288.                     {
  289.             kh_draw->buffer->b_open();
  290.             kh_draw->buffer->screen_buffer();
  291.             kh_draw->buffer->b_close();
  292.                     }
  293.         return;
  294.         }
  295.         else   // We are inside draw, we do not scroll and we use mouse
  296.         draw();
  297.         }
  298.     mouseShowCursor();
  299.     }
  300.     }
  301. /////////////////////
  302. void Draw::load()              // load new file
  303.     {
  304.     int z = (kh_draw->DATA_ZOOM > 0) ? kh_draw->DATA_ZOOM : 100;
  305.     mouseHideCursor();
  306.     kh_draw->buffer->screen_position = rect(loc(0, 0),
  307.     kh_draw->buffer->screen_position.corner
  308.      - kh_draw->buffer->screen_position.origin);
  309.  
  310.     FILE* tmp;
  311.     if((tmp = fopen(global[global_i[1]], "r")) != NULL)
  312.     {
  313.     fclose(tmp);
  314.     kh_draw->buffer->b_open();
  315.     if(pcx_file_buffer(kh_draw->buffer, loc(0, 0), global[global_i[1]]))
  316.             kh_draw->buffer->buffer_screen(loc(z, z), loc(100, 100));
  317.     kh_draw->buffer->b_close();
  318.     }
  319.     mouseShowCursor();
  320.     saved = 1;
  321.     }
  322. /////////////////////
  323. void Draw::show()
  324.     {
  325.     mouseHideCursor();
  326.     Window::show();
  327.     kh_draw->buffer->screen_position = rect(loc(0, 0),
  328.     kh_draw->buffer->screen_position.corner
  329.      - kh_draw->buffer->screen_position.origin);
  330.  
  331.     if(kh_draw->buffer->loaded == 0)
  332.     return;
  333.  
  334.     int z = (kh_draw->DATA_ZOOM > 0) ? kh_draw->DATA_ZOOM : 100;
  335.  
  336.     kh_draw->buffer->b_open();
  337.     kh_draw->buffer->buffer_screen(loc(z, z), loc(100, 100));
  338.     kh_draw->buffer->b_close();
  339.     mouseShowCursor();
  340.     }
  341. //////////////////////
  342. void Draw::repose(rect rec)
  343.     {
  344.     Window::repose(rec);
  345.     rect r = user_screen();
  346. //    r.origin.X += 8 - r.origin.X % 8 + 1;
  347. //    r.corner.X -= r.corner.X % 8;
  348.     r.corner.Y -= 1;
  349.     kh_draw->buffer->screen_area = r;
  350.     kh_draw->buffer->screen_position = rect(0, 0,
  351.                  r.width() - 1, r.height() - 1);
  352.     }
  353. //////////////////////
  354. void Draw::save()
  355.     {
  356.     mouseHideCursor();
  357.     kh_draw->buffer->b_open();
  358.     if(!kh_draw->DATA_ZOOM)
  359.     kh_draw->buffer->screen_buffer();
  360.     kh_draw->buffer->pcx_buffer_file(rect(0, 0,
  361.         (kh_draw->buffer->buf_dim.X - 1) / 8 * 8 - 1,
  362.                 kh_draw->buffer->buf_dim.Y - 1),
  363.                 global[global_i[1]]);
  364.     kh_draw->buffer->b_close();
  365.     mouseShowCursor();
  366.     saved = 1;
  367.     }
  368. ///////////////////////
  369. void Draw::new_file(rect r, int hide)    // clears work area
  370.     {
  371.     mouseHideCursor();
  372.     struct fillsettingstype fillinfo;
  373.     getfillsettings(&fillinfo);
  374.     setfillstyle(SOLID_FILL, getmaxcolor());
  375.  
  376.     bar(r);
  377.     setfillstyle(fillinfo.pattern, fillinfo.color);
  378.     mouseShowCursor();
  379.     if(hide)
  380.     {
  381.     FILE* Buf = fopen(kh_draw->buffer->file_name, "w+b");
  382.     fclose(Buf);
  383.     kh_draw->buffer->screen_position = rect(loc(0, 0),
  384.         kh_draw->buffer->screen_position.corner
  385.         - kh_draw->buffer->screen_position.origin);
  386.  
  387.     kh_draw->buffer->b_open();
  388.     kh_draw->buffer->clear();
  389.     kh_draw->buffer->b_close();
  390.     saved = 1;
  391.     }
  392.     }
  393. /////////////////////
  394. int Draw::cut_copy(char* copyName)
  395.     {
  396.     rect r = user_screen();
  397.     loc mspos = verify_rect(r);
  398.     rect reserv1 = r;
  399.     r.origin.X += 8 - r.origin.X % 8;
  400.     int z = (kh_draw->DATA_ZOOM > 0) ? kh_draw->DATA_ZOOM : 100;
  401.     rect reserv = r;
  402.     if(kh_draw->DATA_ZOOM)
  403.     r = rect(r.origin,
  404.         loc(r.origin.X + (long)kh_draw->buffer->buf_dim.X * 100 / z,
  405.         r.origin.Y + (long)kh_draw->buffer->buf_dim.Y * 100 / z));
  406.     loc minsize = loc(pScreenSet->cell_width, pScreenSet->cell_height);
  407.     rect work = get_dim(FIG_RECTANGLE, RESIZE, reserv1,
  408.     rect(mspos, mspos + minsize));
  409.     r = reserv;
  410.     if(work.origin.X == work.corner.X ||   // cancel operation
  411.        work.origin.Y == work.corner.Y)
  412.     {
  413.     r = reserv1;
  414.     return saved;
  415.     }
  416.     rect reserv4;
  417.     kh_draw->buffer->b_open();
  418.     if(!kh_draw->DATA_ZOOM)
  419.     kh_draw->buffer->screen_buffer();
  420.     kh_draw->buffer->pcx_buffer_file(
  421.          reserv4 =
  422.          rect((kh_draw->buffer->screen_position.origin.X +
  423.              (long)(work.origin.X
  424.              - kh_draw->buffer->screen_area.origin.X)
  425.               * z / 100 + 7) / 8 * 8,
  426.          kh_draw->buffer->screen_position.origin.Y +
  427.              (long)(work.origin.Y
  428.          - kh_draw->buffer->screen_area.origin.Y)
  429.               * z / 100,
  430.      (kh_draw->buffer->screen_position.origin.X +
  431.              (long)(work.corner.X
  432.              - kh_draw->buffer->screen_area.origin.X)
  433.               * z / 100 + 7) / 8 * 8 - 1,
  434.          kh_draw->buffer->screen_position.origin.Y +
  435.              (long)(work.corner.Y
  436.              - kh_draw->buffer->screen_area.origin.Y)
  437.               * z / 100),
  438.          copyName);
  439.     if(kh_draw->DATA_EDIT == 1 && !kh_draw->DATA_ZOOM)    // CUT
  440.     {
  441.         saved = 0;
  442. //    color_bar(work, kh_draw->DATA_FILL, 16);
  443.     color_grad(work, kh_draw->DATA_GRAD);
  444.     }
  445.     else if(kh_draw->DATA_EDIT == 1 && kh_draw->DATA_ZOOM)
  446.     {
  447.         saved = 0;
  448.     setcolor(kh_draw->DATA_ATTR);
  449.     setfillpattern((uchar*)::pattern[kh_draw->DATA_FILL],
  450.                kh_draw->DATA_BAK);
  451.     bar(kh_draw->buffer, reserv4);
  452.     kh_draw->buffer->buffer_screen(work, loc(z, z), loc(100, 100));
  453.     }
  454.     kh_draw->buffer->b_close();
  455.     r = reserv1;
  456.     return saved;
  457.     }
  458. /////////////////////
  459. int Draw::paste(char* copyName)
  460.     {
  461.     rect r = user_screen();
  462.     loc mspos = verify_rect(r);
  463.     rect reserv1 = r;
  464. //    r.origin.X += 8 - r.origin.X % 8;
  465.     pcxheader header;
  466.     if(!get_pcx_header(copyName, &header))
  467.     return saved;;
  468.     int z = (kh_draw->DATA_ZOOM > 0) ? kh_draw->DATA_ZOOM : 100;
  469.     rect reserv = r;
  470.     rect work;
  471.     if(kh_draw->DATA_ZOOM)
  472.     r = rect(r.origin.X + 1, r.origin.Y + 1,
  473.         r.origin.X + ((long)kh_draw->buffer->buf_dim.X - 8) * 100 / z - 1,
  474.         r.origin.Y + (long)kh_draw->buffer->buf_dim.Y * 100 / z - 1);
  475.     loc size((header.x2 - header.x1 + 1) * (long)100 / z,
  476.          (header.y2 - header.y1 + 1) * (long)100 / z);
  477.     int mode = FIG_RECTANGLE;
  478.     if(kh_draw->DATA_PREVIEW && !kh_draw->DATA_ZOOM
  479.         && !strcmp("copy.pcy", copyName))
  480.         mode = FIG_PCX;
  481.     work = get_dim(mode, MOVE, r,
  482.     rect(loc(r.origin.X, r.origin.Y),
  483.          r.origin + size), size);
  484.     r = reserv;
  485.     if(work.origin.X == work.corner.X ||
  486.        work.origin.Y == work.corner.Y)
  487.     {
  488.     r = reserv1;
  489.     return saved;
  490.     }
  491.     mspos = work.origin;
  492.     if(kh_draw->DATA_ZOOM || kh_draw->DATA_TRANS)
  493.     {
  494.     kh_draw->buffer->b_open();
  495.     int col = 17;                  // No such color -> pixel processing
  496.     if(kh_draw->DATA_TRANS)
  497.         col = kh_draw->DATA_BAK;
  498.     pcx_file_buffer(kh_draw->buffer,
  499.         loc((kh_draw->buffer->screen_position.origin.X +
  500.         (long)(mspos.X - kh_draw->buffer->screen_area.origin.X)
  501.               * z / 100), // + 7) / 8 * 8,!!!!!!!!!!!!!!!!!!!!!!!!
  502.         kh_draw->buffer->screen_position.origin.Y +
  503.         (long)(mspos.Y - kh_draw->buffer->screen_area.origin.Y)
  504.         * z / 100),
  505.         copyName, col);
  506.     kh_draw->buffer->buffer_screen(work, loc(z, z), loc(100, 100));
  507.     kh_draw->buffer->b_close();
  508.     }
  509.     else
  510.     pcx_file_scr(copyName, work.origin);
  511.     r = reserv1;
  512.     return 0;
  513.     }
  514. /////////////////////
  515. int Draw::filter_func()
  516.     {
  517.     rect r = user_screen();
  518.     loc mspos = e.where();
  519.     if(kh_draw->DATA_ZOOM)
  520.     return saved;
  521.     loc minsize = loc(pScreenSet->cell_width, pScreenSet->cell_height);
  522.     rect work = get_dim(FIG_RECTANGLE, RESIZE, r,
  523.         rect(mspos, mspos + minsize));
  524.     if(work.origin.X == work.corner.X ||
  525.        work.origin.Y == work.corner.Y)
  526.     return saved;
  527.     int* kernel = read_line_N(kh_draw->DATA_FILTER, "filter.src");
  528.  
  529.     color_filter(kernel, work);
  530.     delete kernel;
  531.     return 0;
  532.     }
  533. ////////////////////
  534. int Draw::dither_func()
  535.     {
  536.     rect r = user_screen();
  537.     loc mspos = e.where();
  538.     int z = (kh_draw->DATA_ZOOM > 0) ? kh_draw->DATA_ZOOM : 100;
  539.     rect reserv = r;
  540.     loc minsize = loc(pScreenSet->cell_width, pScreenSet->cell_height);
  541.     if(kh_draw->DATA_ZOOM)
  542.     r = rect(r.origin,
  543.         loc(r.origin.X + (long)kh_draw->buffer->buf_dim.X * 100 / z,
  544.             r.origin.Y + (long)kh_draw->buffer->buf_dim.Y * 100 / z));
  545.  
  546.     rect work = get_dim(FIG_RECTANGLE, RESIZE, r,
  547.         rect(mspos, mspos + minsize));
  548.     r = reserv;
  549.     if(work.origin.X == work.corner.X ||
  550.        work.origin.Y == work.corner.Y)
  551.     return saved;
  552.     loc dim;
  553.  
  554.     rect work1(kh_draw->buffer->screen_position.origin.X +
  555.              (long)(work.origin.X
  556.              - kh_draw->buffer->screen_area.origin.X)
  557.               * z / 100,
  558.          kh_draw->buffer->screen_position.origin.Y +
  559.              (long)(work.origin.Y
  560.              - kh_draw->buffer->screen_area.origin.Y)
  561.               * z / 100,
  562.          kh_draw->buffer->screen_position.origin.X +
  563.              (long)(work.corner.X
  564.              - kh_draw->buffer->screen_area.origin.X)
  565.               * z / 100,
  566.          kh_draw->buffer->screen_position.origin.Y +
  567.              (long)(work.corner.Y
  568.              - kh_draw->buffer->screen_area.origin.Y)
  569.               * z / 100);
  570.  
  571.     if(kh_draw->DATA_DITHER == 0 && !kh_draw->DATA_ZOOM)    // special case
  572.     {
  573.         if(!kh_draw->DATA_ERROR_PROP)
  574.             for(int y = work.origin.Y; y < work.corner.Y; y++)
  575.             for(int x = work.origin.X;
  576.             x < work.corner.X; x++)
  577.             {
  578.             putpixel(x, y,
  579.                 (bw_pix((uchar)(getpixel(x, y)), x, y)
  580.                ? kh_draw->DATA_BAK : kh_draw->DATA_ATTR));
  581.             }
  582.         else
  583.             error_dither(work);
  584.     return 0;
  585.     }
  586.     int dither[100];
  587.     dim = get_dither(kh_draw->DATA_DITHER, dither);
  588.     if(dim.X == 0)
  589.     return saved;
  590.  
  591.     if(kh_draw->DATA_ZOOM)
  592.     {
  593.     kh_draw->buffer->b_open();
  594.         if(!kh_draw->DATA_ERROR_PROP)
  595.             dither_BW(dither, work1, dim, kh_draw->buffer);
  596.         else
  597.             error_dither_buf(kh_draw->buffer, work1);
  598.  
  599.     kh_draw->buffer->buffer_screen(work, loc(z, z),
  600.                   loc(100, 100));
  601.     kh_draw->buffer->b_close();
  602.     }
  603.     else
  604.     if(!kh_draw->DATA_ERROR_PROP)
  605.         dither_BW(dither, work, dim);
  606.         else
  607.             error_dither(work);
  608.  
  609.     return 0;
  610.     }
  611. ////////////////////
  612. void Draw::draw()                              // draw processing
  613.     {
  614.     global_i[6] = kh_draw->DATA_ATTR;
  615.     global_i[7] = kh_draw->DATA_BAK;
  616.     global_i[8] = kh_draw->DATA_ERROR_PROP;
  617.     global_i[9] = kh_draw->DATA_FILL;
  618.     global_i[12] = kh_draw->DATA_TOOLS;
  619.     rect r = user_screen();                                // work area
  620.     setlinestyle(SOLID_LINE, 1, kh_draw->DATA_LINE);
  621.     setcolor(kh_draw->DATA_ATTR);                                   // draw color
  622. //    setfillpattern(pattern[kh_draw->DATA_FILL], kh_draw->DATA_BAK);
  623.  
  624.     int dis = kh_draw->DATA_LINE;                               // line width - 3
  625.  
  626.     e = readevent();                    // get mouse position
  627.     loc mspos = verify_rect(r);
  628.  
  629.     loc minsize = loc(pScreenSet->cell_width, pScreenSet->cell_height);
  630.     rect work;
  631.     mouseHideCursor();
  632.     switch(kh_draw->DATA_TOOLS)                     // draw function from tools menu
  633.     {
  634.     case TOOL_SCISSORS:
  635.         switch(kh_draw->DATA_EDIT)
  636.         {
  637.         case 1:                  // CUT
  638.         case 2:                  // COPY
  639.             saved = cut_copy();
  640.             break;
  641.         case 6:                   // PASTE
  642.             saved = paste();
  643.             break;
  644.         }
  645.         break;
  646.     case 14:           // Filters
  647.         saved = filter_func();
  648.         break;
  649.     case 15:           // Dither
  650.         saved = dither_func();
  651.         break;
  652.     case 16:           // LOCAL UNDO
  653.         if(kh_draw->DATA_ZOOM)
  654.         break;
  655.         work = get_dim(FIG_RECTANGLE, RESIZE, r,
  656.                 rect(mspos, mspos + minsize),
  657.                 loc(0, 0), loc(1, 1));
  658.         if(work.origin.X != work.corner.X
  659.         && work.origin.Y != work.corner.Y)
  660.         {
  661.                 saved = 0;
  662.         kh_draw->buffer->b_open();
  663.         kh_draw->buffer->buffer_screen(work);
  664.         kh_draw->buffer->b_close();
  665.         }
  666.         break;
  667.     case 3:    // ERASER
  668.     case 4:    // COLOR ERASER
  669.     case 6:    // RECTANGLE
  670.     case 7:    // CIRCLE
  671.     case 8:    // LINE
  672.         if(kh_draw->DATA_ZOOM)
  673.         break;                    // to be changed with KNOW-HOW.VBGI
  674.         int f_type = FIG_RECTANGLE;
  675.         if(kh_draw->DATA_TOOLS == 7)
  676.         f_type = FIG_CIRCLE;
  677.         else if(kh_draw->DATA_TOOLS == 8)
  678.         f_type = FIG_LINE;
  679.         work = get_dim(f_type, RESIZE, r,
  680.                 rect(mspos, mspos + minsize),
  681.                 loc(0, 0), loc(1, 1));
  682.         if(work.origin.X != work.corner.X
  683.         || work.origin.Y != work.corner.Y)
  684.         {
  685.                 saved = 0;
  686.         switch(kh_draw->DATA_TOOLS)
  687.             {
  688.             case 3:                                       // ERASER
  689.             case TOOL_COLOR_ERASER:
  690.             color_grad(work, kh_draw->DATA_GRAD); break;
  691.             case 6:
  692.             while(dis--)
  693.                 {
  694.                 ::rectangle(work);
  695.                 work.origin.X += 1;
  696.                 work.origin.Y += 1;
  697.                 work.corner.X -= 1;
  698.                 work.corner.Y -= 1;
  699.                 }
  700.             break;
  701.             case 7:
  702.             setlinestyle(SOLID_LINE, 1, 1);
  703.             while(dis-- && work.width() > 0 && work.height() > 0)
  704.                 {
  705.                 ellipse(work.origin.X + work.width() / 2,
  706.                 work.origin.Y + work.height() / 2, 0, 360,
  707.                 work.width() / 2, work.height() / 2);
  708.                 work.origin.X += 1;
  709.                 work.origin.Y += 1;
  710.                 work.corner.X -= 1;
  711.                 work.corner.Y -= 1;
  712.                 }
  713.             break;
  714.  
  715.             case 8:
  716.             while(dis--)
  717.                 {
  718.                             //work.sort();
  719.                 line(work.origin, work.corner);
  720.                 loc sh = (abs(work.width()) > abs(work.height()))
  721.                      ? loc(0, 1) : loc(1, 0);
  722.  
  723.                 work.origin.X += sh.X;
  724.                 work.origin.Y -= sh.Y;
  725.                 work.corner.X += sh.X;
  726.                 work.corner.Y -= sh.Y;
  727.                 }
  728.             break;
  729.             }
  730.         }
  731.         break;
  732.     case 5:    // FILL
  733.         if(kh_draw->DATA_ZOOM)
  734.         break;
  735.         char pattern[8];
  736.         getfillpattern(pattern);
  737.             saved = 0;
  738.         fill_area(mspos, kh_draw->DATA_ATTR, kh_draw->DATA_BAK, pattern, r);
  739.         break;
  740.     case 9:    // PEN
  741.         if(kh_draw->DATA_ZOOM)
  742.         break;
  743.         mspos = e.where();
  744.         while(1)
  745.         {
  746.         get_event(2);
  747.  
  748.         if(e.what == MOUSEEVENT
  749.            && (e.msstatus.buttonstate == MOUSERIGHT ||
  750.            e.msstatus.buttonstate == MOUSELEFT || !r.contains(mspos))
  751.             || e.what == KEYEVENT && (e.key == EVENT_RETURN || e.key == EVENT_ESC))
  752.             break;
  753.                 saved = 0;
  754.         if(e.what == KEYEVENT)
  755.             switch(e.key)
  756.             {
  757.             case EVENT_LEFT: mspos.X--; break;
  758.             case EVENT_RIGHT: mspos.X++; break;
  759.             case EVENT_UP: mspos.Y--; break;
  760.             case EVENT_DN: mspos.Y++; break;
  761.             }
  762.         else
  763.             mspos = e.where();
  764.         color_bar(rect(mspos.X, mspos.Y, mspos.X + 2 * kh_draw->DATA_LINE,
  765.             mspos.Y + 2 * kh_draw->DATA_LINE), kh_draw->DATA_FILL, 48);
  766.         }
  767.         break;
  768.     case 10:   // TEXT
  769.         if(kh_draw->DATA_ZOOM)
  770.         break;
  771.         if(kh_draw->fontName == NULL)
  772.         return;
  773.  
  774.         ljfont*  fnt = new ljfont(kh_draw->fontName);
  775.         saved = 0;
  776.         text_edit1(mspos, r, fnt, kh_draw->DATA_SIZE, kh_draw->DATA_DIR, kh_draw->DATA_ATTR);
  777.         break;
  778.     }
  779.     mouseShowCursor();
  780.  
  781.     settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
  782.     settextjustify(LEFT_TEXT, TOP_TEXT);
  783.     }
  784. ////////////////////
  785.  
  786.  
  787.  
  788.  
  789.